﻿using System;
using System.Threading.Tasks;
using Bit.Art.Distributed;
using NetMQ;
using NetMQ.Sockets;

namespace Bit.Art.Broker
{
    public class Program
    {
#if DEBUG
        public static System.Threading.AutoResetEvent s_autoResetEventForTest { get; private set; } = new System.Threading.AutoResetEvent(false);
#endif

        private static NetMQPoller m_Poller;
        private static RouterSocket m_Frontend;
        private static DealerSocket m_Backend;

        static void Main(string[] args)
        {
            var task = StartEngine();
            Task.WaitAll(task);
        }

        public static void StopEngine()
        {
            m_Frontend.Unbind(SiteConfiguration.FrontEndpoint);
            m_Backend.Unbind(SiteConfiguration.BackEndpoint);
            m_Frontend.Dispose();
            m_Backend.Dispose();
            m_Poller.Dispose();
            m_Poller = null;
        }

        public static Task StartEngine()
        {
            // TODO: 需要将硬编码的load balance端口放到配置文件里
            m_Frontend = new RouterSocket($"@{SiteConfiguration.FrontEndpoint}");
            m_Backend = new DealerSocket($"@{SiteConfiguration.BackEndpoint}");

            m_Frontend.ReceiveReady += (s, e) =>
            {
                try
                {
                    var msg = e.Socket.ReceiveMultipartMessage();
                    m_Backend.SendMultipartMessage(msg);
                }
                catch
                {
#if DEBUG
                    s_autoResetEventForTest.Set();
#endif
                }
            };

            m_Backend.ReceiveReady += (s, e) =>
            {
                try
                {
                    var msg = e.Socket.ReceiveMultipartMessage();
                    m_Frontend.SendMultipartMessage(msg);
                }
                catch
                {
#if DEBUG
                    s_autoResetEventForTest.Set();
#endif
                }
            };

            m_Poller = new NetMQPoller { m_Backend, m_Frontend };
            var task = Task.Factory.StartNew(() =>
            {
                try
                {
                    if (m_Poller != null)
                    {
                        m_Poller.Run();
                    }
                }
                catch
                {
#if DEBUG
                    s_autoResetEventForTest.Set();
#endif
                }
            }, TaskCreationOptions.LongRunning);

#if DEBUG
            s_autoResetEventForTest.Set();
#endif
            return task;
        }
    }
}
